using System;
using System.Collections.Generic;
using System.Diagnostics;
using FireStarterModeller.BO;
using FireStarterModeller.Logic;
using Habanero.Base;
using Habanero.Base.Exceptions;
using Habanero.BO;
using Habanero.Faces.Base;

namespace FireStarterModeller.UI
{
    /// <summary>
    /// Creates a <see cref="UIGridInfo"/> and its related <see cref="UIGridFilter"/> based on the inputs from the wizard.
    /// </summary>
    public class CreateViewWizardController : WizardController
    {
        /// <summary>
        /// Gets the <see cref="UIGrid"/> created by this Wizard controller.
        /// </summary>
        public UIGridInfo UIGrid { get; private set; }
        /// <summary>
        /// Gets the <see cref="UIGridFilter"/> Created by this Wizard.
        /// </summary>
        public UIGridFilter GridFilter { get; private set; }

        /// <summary>
        /// Creates a <see cref="CreateViewWizardController"/> of type <see cref="WizardController"/> with the required steps 
        /// for creating a <see cref="UIGridInfo"/> and its related <see cref="UIGridFilter"/>.
        /// </summary>
        public CreateViewWizardController()
        {
            SelectColumnPropertiesWizardStep = new SelectPropertiesWizardStep();
            SelectFilterPropertiesWizardStep = new SelectPropertiesFilterWizardStep();
            SelectFieldPropertiesWizardStep = new SelectPropertiesWizardStep();

            SelectFilterPropertiesWizardStep.ClassSelectorControl.Visible = false;
            this.AddStep(SelectColumnPropertiesWizardStep);
            this.AddStep(SelectFilterPropertiesWizardStep);
            SelectColumnPropertiesWizardStep.ClassSelectorControl.BusinessObjectSelected += ClassSelectorControl_BusinessObjectSelected;
            SelectColumnPropertiesWizardStep.Label.Text = "1. Please select an entity and the properties to show in the grid.";
            SelectFilterPropertiesWizardStep.Label.Text = "2. Please select filters to show for the grid.";
            SelectFieldPropertiesWizardStep.Label.Text = "3. Please select properties to show on the form.";
            SelectFieldPropertiesWizardStep.ClassSelectorControl.Visible = false;
            this.AddStep(SelectFieldPropertiesWizardStep);
        }

        private void ClassSelectorControl_BusinessObjectSelected(object sender, BOEventArgs e)
        {
            try
            {
                var dmClass = (DMClass)e.BusinessObject;
                SelectFilterPropertiesWizardStep.SelectedClass = dmClass;
                SelectFieldPropertiesWizardStep.SelectedClass = dmClass;
                //if (dmClass != null)
                //{
                //    //CheckClassHasUIViews(dmClass);
                //}
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        /// <summary>
        /// The DMClass that the <see cref="UIGridInfo"/> and its related <see cref="UIGridFilter"/> are created for.
        /// </summary>
        public DMClass Class
        {
            get { return SelectColumnPropertiesWizardStep.SelectedClass; }
            set
            {
                //CheckClassHasUIViews(value);
                SelectColumnPropertiesWizardStep.SelectedClass = value;
                SelectFilterPropertiesWizardStep.SelectedClass = value;
                SelectFieldPropertiesWizardStep.SelectedClass = value;
            }
        }

        //private static void CheckClassHasUIViews(DMClass dmClass)
        //{

        //    if (dmClass != null && dmClass.UIViews.Count > 0)   
        //    {
        //        throw new UserException("You cannot create a grid definition for the entity '" + dmClass.ToString() +
        //                                "' as it already has a UIView defined.");
        //    }
        //}
        /// <summary>
        /// The <see cref="DMSolution"/> that the <see cref="UIGridInfo"/> and its related <see cref="UIGridFilter"/> are being created for.
        /// This is used to fill the <see cref="DMClass"/>es that are available.
        /// </summary>
        public DMSolution Solution
        {
            get { return SelectColumnPropertiesWizardStep.Solution; }
            set { SelectColumnPropertiesWizardStep.Solution = value; }
        }

        /// <summary>
        /// Returns the Wizard step that is used to Select the properties that will be used for the filter.
        /// </summary>
        public SelectPropertiesFilterWizardStep SelectFilterPropertiesWizardStep { get; private set; }

        /// <summary>
        /// Returns the Wizard step that is used to Select the properties that will be used for the grid columns.
        /// </summary>
        private SelectPropertiesWizardStep SelectColumnPropertiesWizardStep { get; set; }

        /// <summary>
        /// Returns the Wizard step that is used to Select the properties that will be used for the form fields.
        /// </summary>
        private SelectPropertiesWizardStep SelectFieldPropertiesWizardStep { get; set; }

        ///<summary>
        /// Method that is to be run when the Wizard is finished. This method should do all persistance that is required.
        ///</summary>
        public override void Finish()
        {
            try
            {
                CreateUIView();
                base.Finish();
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex, "", "Error ");
            }
        }

        private void CreateUIView()
        {
            var selectedGridProps = SelectColumnPropertiesWizardStep.PropertiesSelectorControl.SelectedOptions;
            var selectedFilerOptions = SelectFilterPropertiesWizardStep.PropertiesSelectorControl.SelectedOptions;
            var selectedFormOptions = SelectFieldPropertiesWizardStep.PropertiesSelectorControl.SelectedOptions;

            var uiView = CreateUIView(this.Class, selectedGridProps, selectedFilerOptions, selectedFormOptions);
            uiView.Save();
        }

        protected UIView CreateUIView(DMClass dmClass, IList<string> selectedGridProps, IList<string> selectedFilterProps, IList<string> selectedFormProps)
        {
            CreateGrid(dmClass, selectedGridProps);
            CreateFilter(selectedFilterProps);

            var formCreator = new UIFormCreator();
            UIFormInfo uiFormInfo = formCreator.CreateUIForm(dmClass, selectedFormProps);


            var uiViews = dmClass.UIViews;
            var uiView = uiViews.CreateBusinessObject();
            uiView.UIFormInfo = uiFormInfo;

           //var uiViews = dmClass.UIViews;
           //var uiView = uiViews.CreateBusinessObject();
            uiView.UIGridInfo = UIGrid;

            uiView.ViewName = dmClass.GetUniqueViewNameWithSuffix(uiView.ViewName);

            return uiView;
        }

        protected static UIFormInfo CreateForm(DMClass dmClass, IList<string> selectedFormProps)
        {
            if (selectedFormProps.Count == 0) return null;

            var boEditorCreator = new UIFormCreator();

            return boEditorCreator.CreateUIForm(dmClass, selectedFormProps);
        }

        protected void CreateGrid(DMClass dmClass, IList<string> selectedGridProps)
        {
            var uiGridCreator = new UIGridCreator();
            UIGrid = uiGridCreator.CreateGrid(dmClass, selectedGridProps);
        }

        private void CreateFilter(IList<string> selectedFilterProps)
        {
            var gridFilterCreator = new UIGridFilterCreator(Solution);
            if (selectedFilterProps.Count > 0)
            {
                GridFilter = gridFilterCreator.CreateUIGridFilter(selectedFilterProps);
                UIGrid.UIGridFilter = GridFilter;
            }
        }

        ///<summary>
        /// Checks if the Wizard can proceed to the next step. Calls through to the CanMoveOn method of the current IWizardStep. 
        /// You can move on from Select Grid Column Properties as long as you have selects some Grid Properties.         
        ///</summary>
        ///
        ///<param name="message">Describes why the Wizard cannot move on. Only applicable if CanMoveOn returns false.</param>
        ///<returns>
        ///True if moving to the next step is allowed.
        ///</returns>
        ///
        public override bool CanMoveOn(out string message)
        {
            base.CanMoveOn(out message);
            MultiSelectorModel<string> multiSelectorModel = SelectColumnPropertiesWizardStep.PropertiesSelectorControl.Model;
            if (CurrentStep == 0)
            {
                //CheckClassHasUIViews(this.SubClass);
                if (multiSelectorModel.SelectedOptions.Count == 0)
                {
                    message += Environment.NewLine + "You must select properties to show in the grid before you can move on";
                }
            }
            if (CurrentStep == 0)
            {
                SelectFilterPropertiesWizardStep.PropertiesSelectorControl.AllOptions = multiSelectorModel.SelectedOptions;
            }
            return message.Length <= 0;
        }
    }

}